<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>第一人称动漫钓鱼游戏</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Comic Sans MS', cursive;
            overflow: hidden;
            user-select: none;
            cursor: none;
        }
        
        #gameCanvas {
            display: block;
        }
        
        .crosshair {
            position: absolute;
            width: 20px;
            height: 20px;
            border: 2px solid rgba(255, 255, 255, 0.8);
            border-radius: 50%;
            pointer-events: none;
            z-index: 15;
            transform: translate(-50%, -50%);
        }
        
        .crosshair::after {
            content: '';
            position: absolute;
            top: 50%;
            left: 50%;
            width: 4px;
            height: 4px;
            background: rgba(255, 255, 255, 0.8);
            border-radius: 50%;
            transform: translate(-50%, -50%);
        }
        
        .ui {
            position: absolute;
            top: 20px;
            left: 20px;
            color: white;
            font-size: 18px;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
            z-index: 10;
        }
        
        .weather-info {
            position: absolute;
            top: 20px;
            right: 20px;
            color: white;
            font-size: 16px;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
            z-index: 10;
        }
        
        .instructions {
            position: absolute;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            color: white;
            font-size: 16px;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
            z-index: 10;
            text-align: center;
        }
        
        .fish-caught {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: linear-gradient(45deg, #FF6B9D, #4ECDC4);
            padding: 20px 30px;
            border-radius: 20px;
            border: 3px solid #FFD93D;
            font-size: 28px;
            font-weight: bold;
            color: white;
            display: none;
            z-index: 20;
            animation: fishCaughtAnimation 0.8s ease-in-out;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
        }
        
        @keyframes fishCaughtAnimation {
            0% { transform: translate(-50%, -50%) scale(0.5) rotate(-10deg); opacity: 0; }
            50% { transform: translate(-50%, -50%) scale(1.2) rotate(0deg); opacity: 1; }
            100% { transform: translate(-50%, -50%) scale(1) rotate(0deg); opacity: 1; }
        }
        
        .bucket-counter {
            position: absolute;
            bottom: 100px;
            right: 20px;
            background: linear-gradient(45deg, #8B4513, #D2691E);
            padding: 15px 20px;
            border-radius: 15px;
            color: white;
            font-size: 18px;
            border: 3px solid #FFD700;
            box-shadow: 0 5px 15px rgba(0,0,0,0.3);
        }
        
        .rod-power {
            position: absolute;
            bottom: 20px;
            right: 20px;
            width: 200px;
            height: 20px;
            background: rgba(0,0,0,0.5);
            border-radius: 10px;
            border: 2px solid white;
            overflow: hidden;
        }
        
        .power-fill {
            height: 100%;
            background: linear-gradient(90deg, #4CAF50, #FFC107, #FF5722);
            width: 0%;
            transition: width 0.1s ease;
            border-radius: 8px;
        }
        
        .rod-hands {
            position: absolute;
            bottom: 0;
            left: 50%;
            transform: translateX(-50%);
            z-index: 5;
        }
    </style>
</head>
<body>
    <canvas id="gameCanvas"></canvas>
    <div class="crosshair" id="crosshair"></div>
    
    <div class="ui">
        <div>🎣 得分: <span id="score">0</span></div>
        <div>🐟 钓鱼数: <span id="totalFish">0</span></div>
        <div>⭐ 连击: <span id="combo">0</span></div>
    </div>
    
    <div class="weather-info">
        <div id="weatherDisplay">🌤️ 天气: 晴朗</div>
        <div id="timeDisplay">🕐 时间: 上午</div>
    </div>
    
    <div class="instructions">
        <div>🎮 按住鼠标左键蓄力甩竿 | 空格键收鱼入桶</div>
        <div>🐠 鱼儿会主动游向你的鱼钩哦！</div>
    </div>
    
    <div class="bucket-counter">
        <div>🪣 鱼桶收藏</div>
        <div>鱼数: <span id="bucketCount">0</span></div>
    </div>
    
    <div class="rod-power">
        <div class="power-fill" id="powerFill"></div>
    </div>
    
    <div id="fishCaught" class="fish-caught">
        <div id="fishMessage"></div>
    </div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        
        // 设置画布大小
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        
        // 游戏状态
        let gameState = {
            score: 0,
            totalFish: 0,
            bucketCount: 0,
            combo: 0,
            weather: 'sunny',
            timeOfDay: 'morning',
            rodCast: false,
            rodPower: 0,
            chargingRod: false,
            rodAngle: 0,
            hookX: canvas.width / 2,
            hookY: canvas.height * 0.7,
            caughtFish: null,
            fishInWater: [],
            lastFishSpawn: 0,
            weatherChangeTimer: 0,
            timeChangeTimer: 0,
            mouseX: canvas.width / 2,
            mouseY: canvas.height / 2,
            rodAnimation: 0
        };
        
        // 鱼类定义
        const fishTypes = [
            { name: '小丑鱼', color: '#FF6B6B', size: 18, points: 15, rarity: 0.35, emoji: '🐠' },
            { name: '天使鱼', color: '#4ECDC4', size: 25, points: 25, rarity: 0.25, emoji: '🐟' },
            { name: '热带鱼', color: '#45B7D1', size: 22, points: 20, rarity: 0.25, emoji: '🐡' },
            { name: '章鱼', color: '#E74C3C', size: 35, points: 50, rarity: 0.1, emoji: '🐙' },
            { name: '金龙鱼', color: '#F1C40F', size: 30, points: 100, rarity: 0.04, emoji: '🐲' },
            { name: '彩虹鱼', color: '#9B59B6', size: 28, points: 80, rarity: 0.06, emoji: '🌈' }
        ];
        
        // 天气系统
        const weatherTypes = {
            sunny: { name: '晴朗', skyColor: '#87CEEB', waterColor: '#4169E1', emoji: '🌤️' },
            cloudy: { name: '阴天', skyColor: '#B0C4DE', waterColor: '#4682B4', emoji: '☁️' },
            rain: { name: '雨天', skyColor: '#708090', waterColor: '#2F4F4F', emoji: '🌧️' },
            sunset: { name: '日落', skyColor: '#FF7F50', waterColor: '#FF6347', emoji: '🌅' }
        };
        
        // 更新鼠标位置
        canvas.addEventListener('mousemove', (e) => {
            gameState.mouseX = e.clientX;
            gameState.mouseY = e.clientY;
            
            // 更新准星位置
            const crosshair = document.getElementById('crosshair');
            crosshair.style.left = e.clientX + 'px';
            crosshair.style.top = e.clientY + 'px';
        });
        
        // 生成鱼类
        function spawnFish() {
            if (Date.now() - gameState.lastFishSpawn > 1500 + Math.random() * 2000) {
                // 根据稀有度选择鱼类
                let totalRarity = fishTypes.reduce((sum, fish) => sum + fish.rarity, 0);
                let random = Math.random() * totalRarity;
                let selectedFish = fishTypes[0];
                
                for (let fish of fishTypes) {
                    random -= fish.rarity;
                    if (random <= 0) {
                        selectedFish = fish;
                        break;
                    }
                }
                
                const fish = {
                    ...selectedFish,
                    x: Math.random() * (canvas.width - 200) + 100,
                    y: canvas.height * 0.65 + Math.random() * (canvas.height * 0.25),
                    vx: (Math.random() - 0.5) * 1.5,
                    vy: (Math.random() - 0.5) * 0.8,
                    id: Date.now() + Math.random(),
                    attracted: false,
                    attractionTimer: 0
                };
                gameState.fishInWater.push(fish);
                gameState.lastFishSpawn = Date.now();
            }
        }
        
        // 更新鱼群 - 鱼儿主动游向鱼钩
        function updateFish() {
            gameState.fishInWater = gameState.fishInWater.filter(fish => {
                // 如果鱼钩在水中，鱼儿会被吸引
                if (gameState.rodCast && gameState.hookY > canvas.height * 0.6) {
                    const distanceToHook = Math.sqrt(
                        Math.pow(fish.x - gameState.hookX, 2) + 
                        Math.pow(fish.y - gameState.hookY, 2)
                    );
                    
                    // 在一定范围内的鱼会被吸引
                    if (distanceToHook < 150) {
                        fish.attracted = true;
                        fish.attractionTimer++;
                        
                        // 计算向鱼钩游动的方向
                        const angle = Math.atan2(gameState.hookY - fish.y, gameState.hookX - fish.x);
                        const attractionStrength = Math.max(0.5, 2 - distanceToHook / 100);
                        
                        fish.vx = Math.cos(angle) * attractionStrength;
                        fish.vy = Math.sin(angle) * attractionStrength;
                        
                        // 如果足够接近，鱼儿上钩
                        if (distanceToHook < fish.size + 10 && Math.random() < 0.05) {
                            catchFish(fish);
                            return false;
                        }
                    } else {
                        fish.attracted = false;
                    }
                } else {
                    // 正常游动
                    fish.x += fish.vx;
                    fish.y += fish.vy;
                    
                    // 随机改变方向
                    if (Math.random() < 0.03) {
                        fish.vx = (Math.random() - 0.5) * 2;
                        fish.vy = (Math.random() - 0.5) * 1;
                    }
                }
                
                if (!fish.attracted) {
                    fish.x += fish.vx;
                    fish.y += fish.vy;
                }
                
                // 边界检查
                if (fish.x < -50 || fish.x > canvas.width + 50 || 
                    fish.y < canvas.height * 0.6 - 50 || fish.y > canvas.height + 50) {
                    return false;
                }
                
                return true;
            });
        }
        
        // 钓到鱼
        function catchFish(fish) {
            gameState.caughtFish = fish;
            gameState.score += fish.points * (1 + gameState.combo * 0.1);
            gameState.totalFish++;
            gameState.combo++;
            showFishCaught(fish);
            
            // 从鱼群中移除
            gameState.fishInWater = gameState.fishInWater.filter(f => f.id !== fish.id);
        }
        
        // 显示钓到鱼的消息
        function showFishCaught(fish) {
            const fishMessage = document.getElementById('fishMessage');
            const fishCaught = document.getElementById('fishCaught');
            
            const bonusPoints = Math.floor(fish.points * gameState.combo * 0.1);
            fishMessage.innerHTML = `
                ${fish.emoji} 钓到了 ${fish.name}！<br>
                🎯 基础分数: ${fish.points}<br>
                ${bonusPoints > 0 ? `⚡ 连击奖励: +${bonusPoints}<br>` : ''}
                💫 总得分: +${fish.points + bonusPoints}
            `;
            fishCaught.style.display = 'block';
            
            setTimeout(() => {
                fishCaught.style.display = 'none';
            }, 3000);
        }
        
        // 更新天气
        function updateWeather() {
            if (Date.now() - gameState.weatherChangeTimer > 20000) {
                const weathers = Object.keys(weatherTypes);
                gameState.weather = weathers[Math.floor(Math.random() * weathers.length)];
                gameState.weatherChangeTimer = Date.now();
            }
            
            if (Date.now() - gameState.timeChangeTimer > 30000) {
                const times = ['morning', 'afternoon', 'evening', 'night'];
                gameState.timeOfDay = times[Math.floor(Math.random() * times.length)];
                gameState.timeChangeTimer = Date.now();
            }
        }
        
        // 绘制第一人称手部和钓鱼竿
        function drawFirstPersonView() {
            // 绘制手臂和钓鱼竿
            const handX = canvas.width * 0.85;
            const handY = canvas.height * 0.8;
            
            // 手臂
            ctx.fillStyle = '#FDBCB4';
            ctx.beginPath();
            ctx.ellipse(canvas.width * 0.9, canvas.height * 0.9, 80, 40, Math.PI * 0.3, 0, Math.PI * 2);
            ctx.fill();
            
            // 钓鱼竿
            const rodLength = 200;
            const rodAngle = gameState.chargingRod ? 
                -Math.PI * 0.3 - gameState.rodPower * 0.01 : 
                -Math.PI * 0.25 + Math.sin(gameState.rodAnimation * 0.1) * 0.1;
            
            const rodEndX = handX + Math.cos(rodAngle) * rodLength;
            const rodEndY = handY + Math.sin(rodAngle) * rodLength;
            
            // 竿身
            ctx.strokeStyle = '#8B4513';
            ctx.lineWidth = 8;
            ctx.lineCap = 'round';
            ctx.beginPath();
            ctx.moveTo(handX, handY);
            ctx.lineTo(rodEndX, rodEndY);
            ctx.stroke();
            
            // 竿身装饰
            ctx.strokeStyle = '#A0522D';
            ctx.lineWidth = 3;
            ctx.beginPath();
            ctx.moveTo(handX + 20, handY + 10);
            ctx.lineTo(rodEndX - 20, rodEndY - 10);
            ctx.stroke();
            
            // 鱼线
            if (gameState.rodCast) {
                ctx.strokeStyle = 'rgba(200, 200, 200, 0.8)';
                ctx.lineWidth = 2;
                ctx.setLineDash([5, 5]);
                ctx.beginPath();
                ctx.moveTo(rodEndX, rodEndY);
                ctx.lineTo(gameState.hookX, gameState.hookY);
                ctx.stroke();
                ctx.setLineDash([]);
                
                // 鱼钩
                ctx.fillStyle = '#C0C0C0';
                ctx.beginPath();
                ctx.arc(gameState.hookX, gameState.hookY, 6, 0, Math.PI * 2);
                ctx.fill();
                
                // 钩上的鱼
                if (gameState.caughtFish) {
                    const fish = gameState.caughtFish;
                    ctx.fillStyle = fish.color;
                    ctx.beginPath();
                    ctx.ellipse(gameState.hookX, gameState.hookY - 25, fish.size * 0.7, fish.size * 0.4, 0, 0, Math.PI * 2);
                    ctx.fill();
                    
                    // 鱼眼睛
                    ctx.fillStyle = 'white';
                    ctx.beginPath();
                    ctx.arc(gameState.hookX + fish.size * 0.2, gameState.hookY - 30, 4, 0, Math.PI * 2);
                    ctx.fill();
                    
                    ctx.fillStyle = 'black';
                    ctx.beginPath();
                    ctx.arc(gameState.hookX + fish.size * 0.25, gameState.hookY - 30, 2, 0, Math.PI * 2);
                    ctx.fill();
                }
            }
        }
        
        // 主渲染函数
        function render() {
            // 清空画布
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            const currentWeather = weatherTypes[gameState.weather];
            
            // 绘制天空渐变
            const skyGradient = ctx.createLinearGradient(0, 0, 0, canvas.height * 0.6);
            skyGradient.addColorStop(0, currentWeather.skyColor);
            skyGradient.addColorStop(1, '#B0E0E6');
            ctx.fillStyle = skyGradient;
            ctx.fillRect(0, 0, canvas.width, canvas.height * 0.6);
            
            // 绘制水面
            const waterGradient = ctx.createLinearGradient(0, canvas.height * 0.6, 0, canvas.height);
            waterGradient.addColorStop(0, currentWeather.waterColor);
            waterGradient.addColorStop(0.5, '#1E90FF');
            waterGradient.addColorStop(1, '#000080');
            ctx.fillStyle = waterGradient;
            ctx.fillRect(0, canvas.height * 0.6, canvas.width, canvas.height * 0.4);
            
            // 动态水波纹
            ctx.strokeStyle = 'rgba(255, 255, 255, 0.4)';
            ctx.lineWidth = 2;
            const time = Date.now() * 0.002;
            for (let i = 0; i < 8; i++) {
                ctx.beginPath();
                ctx.moveTo(0, canvas.height * 0.6 + i * 15);
                for (let x = 0; x < canvas.width; x += 10) {
                    const wave = Math.sin(x * 0.01 + time + i * 0.5) * (3 + i * 0.5);
                    ctx.lineTo(x, canvas.height * 0.6 + i * 15 + wave);
                }
                ctx.stroke();
            }
            
            // 绘制鱼群
            gameState.fishInWater.forEach(fish => {
                // 鱼儿发光效果（如果被吸引）
                if (fish.attracted) {
                    ctx.shadowColor = fish.color;
                    ctx.shadowBlur = 20;
                }
                
                // 鱼身体
                ctx.fillStyle = fish.color;
                ctx.beginPath();
                ctx.ellipse(fish.x, fish.y, fish.size, fish.size * 0.6, 0, 0, Math.PI * 2);
                ctx.fill();
                
                // 鱼尾巴
                ctx.beginPath();
                ctx.moveTo(fish.x - fish.size, fish.y);
                ctx.lineTo(fish.x - fish.size * 1.3, fish.y - fish.size * 0.4);
                ctx.lineTo(fish.x - fish.size * 1.3, fish.y + fish.size * 0.4);
                ctx.closePath();
                ctx.fill();
                
                // 鱼鳍
                ctx.fillStyle = `${fish.color}80`;
                ctx.beginPath();
                ctx.ellipse(fish.x - fish.size * 0.3, fish.y - fish.size * 0.8, fish.size * 0.3, fish.size * 0.2, 0, 0, Math.PI * 2);
                ctx.fill();
                ctx.beginPath();
                ctx.ellipse(fish.x - fish.size * 0.3, fish.y + fish.size * 0.8, fish.size * 0.3, fish.size * 0.2, 0, 0, Math.PI * 2);
                ctx.fill();
                
                // 鱼眼睛
                ctx.shadowBlur = 0;
                ctx.fillStyle = 'white';
                ctx.beginPath();
                ctx.arc(fish.x + fish.size * 0.3, fish.y - fish.size * 0.2, fish.size * 0.15, 0, Math.PI * 2);
                ctx.fill();
                
                ctx.fillStyle = 'black';
                ctx.beginPath();
                ctx.arc(fish.x + fish.size * 0.35, fish.y - fish.size * 0.2, fish.size * 0.08, 0, Math.PI * 2);
                ctx.fill();
                
                // 被吸引时的爱心特效
                if (fish.attracted && fish.attractionTimer % 30 < 15) {
                    ctx.fillStyle = '#FF69B4';
                    ctx.font = `${fish.size * 0.5}px Arial`;
                    ctx.fillText('💕', fish.x - fish.size * 0.5, fish.y - fish.size);
                }
            });
            
            // 绘制第一人称视角
            drawFirstPersonView();
            
            // 雨天特效
            if (gameState.weather === 'rain') {
                ctx.strokeStyle = 'rgba(200, 200, 255, 0.8)';
                ctx.lineWidth = 2;
                for (let i = 0; i < 150; i++) {
                    const x = Math.random() * canvas.width;
                    const y = (Date.now() * 0.02 + i * 30) % canvas.height;
                    ctx.beginPath();
                    ctx.moveTo(x, y);
                    ctx.lineTo(x - 3, y + 15);
                    ctx.stroke();
                }
            }
            
            gameState.rodAnimation++;
        }
        
        // 鼠标事件
        let mouseDown = false;
        
        canvas.addEventListener('mousedown', (e) => {
            if (e.button === 0) {
                mouseDown = true;
                gameState.chargingRod = true;
                gameState.combo = Math.max(0, gameState.combo - 1); // 连击衰减
            }
        });
        
        canvas.addEventListener('mouseup', (e) => {
            if (e.button === 0 && mouseDown) {
                mouseDown = false;
                gameState.chargingRod = false;
                
                if (gameState.rodPower > 20) {
                    // 甩竿
                    gameState.rodCast = true;
                    const angle = Math.atan2(gameState.mouseY - canvas.height * 0.8, gameState.mouseX - canvas.width * 0.85);
                    const power = Math.min(gameState.rodPower, 100);
                    
                    gameState.hookX = canvas.width * 0.85 + Math.cos(angle) * (power * 3);
                    gameState.hookY = Math.max(canvas.height * 0.65, canvas.height * 0.8 + Math.sin(angle) * (power * 2));
                }
                
                gameState.rodPower = 0;
            }
        });
        
        // 蓄力系统
        function updateRodPower() {
            if (gameState.chargingRod) {
                gameState.rodPower = Math.min(gameState.rodPower + 2, 100);
            }
            
            // 更新蓄力条
            const powerFill = document.getElementById('powerFill');
            powerFill.style.width = gameState.rodPower + '%';
        }
        
        // 键盘事件
        document.addEventListener('keydown', (e) => {
            if (e.code === 'Space') {
                e.preventDefault();
                if (gameState.caughtFish) {
                    gameState.bucketCount++;
                    gameState.caughtFish = null;
                    gameState.rodCast = false;
                } else if (gameState.rodCast && !gameState.caughtFish) {
                    // 收竿
                    gameState.rodCast = false;
                }
            }
        });
        
        // 更新UI
        function updateUI() {
            document.getElementById('score').textContent = gameState.score.toLocaleString();
            document.getElementById('totalFish').textContent = gameState.totalFish;
            document.getElementById('bucketCount').textContent = gameState.bucketCount;
            document.getElementById('combo').textContent = gameState.combo;
            
            const weather = weatherTypes[gameState.weather];
            document.getElementById('weatherDisplay').textContent = `${weather.emoji} 天气: ${weather.name}`;
            
            const timeEmojis = { morning: '🌅', afternoon: '☀️', evening: '🌇', night: '🌙' };
            const timeNames = { morning: '上午', afternoon: '下午', evening: '傍晚', night: '夜晚' };
            document.getElementById('timeDisplay').textContent = 
                `${timeEmojis[gameState.timeOfDay]} 时间: ${timeNames[gameState.timeOfDay]}`;
        }
        
        // 游戏主循环
        function gameLoop() {
            spawnFish();
            updateFish();
            updateRodPower();
            updateWeather();
            render();
            updateUI();
            requestAnimationFrame(gameLoop);
        }
        
        // 初始化游戏
        gameState.weatherChangeTimer = Date.now();
        gameState.timeChangeTimer = Date.now();
        
        // 初始化准星位置
        const crosshair = document.getElementById('crosshair');
        crosshair.style.left = canvas.width / 2 + 'px';
        crosshair.style.top = canvas.height / 2 + 'px';
        
        gameLoop();
        
        // 窗口大小调整
        window.addEventListener('resize', () => {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        });
    </script>
</body>
</html>